<template>
  <div class="login">
    <el-form class="form" :model="loginForm" :rules="rules" ref="loginRef">
      <h3>登 录</h3>
      <el-form-item prop="username">
        <el-input type="text" v-model="loginForm.username" placeholder="请输入用户名">
          <template #prefix>
            <i class="iconfont icon-yonghuming"></i>
          </template>
        </el-input>
      </el-form-item>
      <el-form-item prop="password">
        <el-input type="password" v-model="loginForm.password" placeholder="请输入密码" show-password>
          <template #prefix>
            <i class="iconfont icon-mima"></i>
          </template>
        </el-input>
      </el-form-item>
      <el-form-item prop="code">
        <div style="display: inline-flex;justify-content: space-between;width: 100%;">
          <el-input type="text" v-model="loginForm.code" style="width: 170px;" placeholder="请输入验证码">
            <template #prefix>
              <i class="iconfont icon-yanzhengma"></i>
            </template>
          </el-input>
          <img :src="state.image" @click="getCode">
        </div>
      </el-form-item>
      <el-form-item>
        <el-checkbox v-model="loginForm.rememberMe" style="margin-right: 10px">记住我</el-checkbox>
        <el-link type="danger" :underline="false" @click.prevent="resetPassward">忘记密码？</el-link>
        <el-link type="warning" :underline="false" @click.prevent="resetPassward">立即注册</el-link>
      </el-form-item>
      <el-form-item>
        <el-button class="button" type="primary" size="default" :loading="isLoading" @click.prevent="submitLogin(loginRef)">
          <span v-if="!isLoading">登 录</span>
          <span v-else>登 录 中...</span>
        </el-button>
      </el-form-item>

      <div class="three-party-login">
        <el-divider>其他方式登录</el-divider>
      </div>

      <div class="three-party-icon">
        <span class="login-third-item login-third-qq" @click="LoginClick('qq')"></span>
        <span class="login-third-item login-third-gitee" @click="doSocialLogin('gitee')"></span>
      </div>
    </el-form>

    <!--  底部  -->
    <div class="items-center">
      <el-link
        href="https://beian.mps.gov.cn/#/query/webSearch?code=36112802000156"
        rel="external nofollow"
        target="_blank"
        type="primary"
        ><img src="./assets/image/beian.png" style="height: 13px;"/>赣公网安备36112802000156号
      </el-link>
      <el-link
        href="https://beian.miit.gov.cn"
        rel="external nofollow"
        target="_blank"
        type="primary"
        >赣ICP备2023013972号-1
      </el-link>
    </div>
  </div>
</template>

<script setup>
import './assets/css/login.css'
import {useStore} from "./store";
import routers from "./router/routers";
import {login, quickLogin, getVerifyCode, getQQCode, authBinding} from "./api/login/login";
import {successMsg, errorMsg} from "./utils/message";
import {ref, reactive, onMounted} from 'vue'
import CryptoJS from 'crypto-js';

  const store = useStore()

  const loginRef = ref(null)

  const isLoading = ref(false)

  const state = reactive({
    image: ''
  })

  const loginForm = reactive({
    username: '',
    password: '',
    code: '',
    uuid: '',
    rememberMe: false
  })

  const rules = reactive({
    username: [{ required: true, message: '用户名不能为空', trigger: 'blur' }],
    password: [{ required: true, message: '密码不能为空', trigger: 'blur' }],
    code: [{ required: true, message: '验证码不能为空', trigger: 'blur' }]
  })

  onMounted(() => {
    getCode();
    getLoginData();
  })

  //  获取验证码
  const getCode = () =>{
    getVerifyCode().then(res => {
      if (res.code == 200){
        state.image = res.data.img
        loginForm.uuid = res.data.uuid
      }else{
        errorMsg(res.message)
      }
    })
  }

  const submitLogin = (loginRef) => {
    loginRef.validate((valid) => {
      if (valid){
        isLoading.value = true
        // 勾选了需要记住密码设置在 localStorage 中设置记住用户名和密码
        if (loginForm.rememberMe) {
          localStorage.setItem('username', String(loginForm.username));
          localStorage.setItem('password', String(loginForm.password));
          localStorage.setItem('rememberMe', String(loginForm.rememberMe));
        } else {
          // 否则移除
          localStorage.removeItem('username');
          localStorage.removeItem('password');
          localStorage.removeItem('rememberMe');
        }
        const data = {
          username: loginForm.username,
          password: encrypt(loginForm.password),
          code: loginForm.code,
          uuid: loginForm.uuid
        }
        login(data).then(res => {
          if (res.code == 200){
            //  缓存token
            store.token = res.data.token
            //  缓存刷新token
            store.refreshToken = res.data.refreshToken
            //  缓存当前登录用户信息
            store.userInfo = res.data.userDto
            //  切换到首页
            routers.push({path: '/Layout'})
          } else {
            errorMsg(res.message)
          }
          isLoading.value = false
        })
      }
    })
  }

  /**
   * 记住我
   */
  const getLoginData = () => {
    const username = localStorage.getItem('username');
    const password = localStorage.getItem('password');
    const rememberMe = localStorage.getItem('rememberMe');
    loginForm.username = username === null ? '': username
    loginForm.password = password === null ? '': password
    loginForm.rememberMe = rememberMe === null ? false: Boolean(rememberMe)
  };

  /**
   * 重置密码
   */
  const resetPassward = () => {
    errorMsg("该功能暂未完成，请耐心等待！")
  }

  /**
   * 原生QQ登录
   * @param value 类型
   */
  const LoginClick = (value) => {
    if(value == 'qq'){
      getQQCode().then(res => {
        const url = res.data.url
        const uuid = res.data.uuid
        quickAuthLogin(url, uuid);
      }).catch(fail => {
        errorMsg(fail)
      })
    }
  }

  /**
   * 第三方登录
   * @param type 类型
   */
  const doSocialLogin = (type) => {
    authBinding(type).then((res) => {
      if (res.code === 200) {
        const url = res.data.url
        const uuid = res.data.uuid
        quickAuthLogin(url, uuid);
      } else {
        errorMsg(res.msg);
      }
    }).catch(fail => {
        errorMsg(fail)
      });
  };

  /**
   * 弹窗
   * @param url 地址
   * @param uuid 标识
   */
  const quickAuthLogin = (url, uuid)=>{
    var width = width || 900;
    var height = height || 540;
    var left = (window.screen.width - width) / 2;
    var top = (window.screen.height - height) / 2;
    var win = window.open(url, "_blank",
      "toolbar=yes, location=yes, directories=no, status=no, menubar=yes, scrollbars=yes, resizable=no, copyhistory=yes, left=" +
      left + ", top=" + top + ", width=" + width + ", height=" + height);
    //  监听登录窗口是否关闭,登录成功后 后端返回关闭窗口的代码
    var listener = setInterval(function(){
      //  监听窗口是否关闭
      if(win.closed){
        //  进入这个if代表后端验证成功!直接跳转路由
        clearInterval(listener);//关闭监听
        //  调用登录接口，生成token
        quickLogin({uuid: uuid}).then(res => {
          if (res.code == 200){
            //  缓存token
            store.token = res.data.token
            //  缓存刷新token
            store.refreshToken = res.data.refreshToken
            //  缓存当前登录用户信息
            store.userInfo = res.data.userDto
            //  切换到首页
            routers.push({path: '/Layout'})
            //  提示
            successMsg("登录成功！")
          } else {
            errorMsg(res.message)
          }
        })
      }
    },500)
  }

  // 设置秘钥和秘钥偏移量
  const SECRET_KEY = CryptoJS.enc.Utf8.parse("LySa20240000-***");
  const SECRET_IV = CryptoJS.enc.Utf8.parse("LySa20240000-***");

  // 加密方法
  const encrypt = (word) =>{
    let srcs = CryptoJS.enc.Utf8.parse(word);
    let encrypted = CryptoJS.AES.encrypt(srcs, SECRET_KEY, {
        iv: SECRET_IV ,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.ZeroPadding
    })
    return CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
  }

  // 解密方法
  const decrypt = (word) =>{
    let base64  = CryptoJS.enc.Base64.parse(word);
    let srcs = CryptoJS.enc.Base64.stringify(base64);
    const decrypt = CryptoJS.AES.decrypt(srcs, SECRET_KEY, {
      iv: SECRET_IV ,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.ZeroPadding
    });
    const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
    return decryptedStr;
  }

</script>

<style scoped>
.three-party-login{
  text-align: center;
  color: gray;
  font-size: 12px;
}
.three-party-icon{
  text-align: center;
  color: gray;
  font-size: 12px;
}
.three-party-icon .login-third-item{
  display: inline-block;
  width: 32px;
  height: 32px;
  border-radius: 50% 50%;
  background: #ccc;
  cursor: pointer;
  margin-left: 10px;
}
.three-party-icon .login-third-qq{    
  background: url(./assets/image/QQ-circle-fill.png) no-repeat 50%/cover;
}
.three-party-icon .login-third-gitee{    
  background: url(./assets/image/gitee-copy.png) no-repeat 50%/cover;
}
.items-center{
  margin-bottom: 10px;
  font-size: 14px;
  position: absolute;
  vertical-align: bottom;
  bottom: 0;
  left: 0;
  right: 0;
  text-align: center;
}
.el-link {
  margin-right: 8px;
}
</style>